-
Notifications
You must be signed in to change notification settings - Fork 51
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Change how handles are constructed, so that we can ensure non-null handles #136
Conversation
I understand the motivation behind that and I agree that it's sort of useful to do so. Certain data is mandatory for a handle to be valid and useful in the first place. I'm just not sure how fragile it could be in the wild. Some pointers could be nullable, like display on X11, because users could try to get some sort of default. |
Yeah, I definitely need everybody's guidance on where a null pointer does or does not make sense (e.g. a null pointer NSView is definitely nonsense, there's nothing you can feasibly fall back to, but for others it may). |
61f632a
to
8c3dfb1
Compare
By the way, it's generally a bad idea to just "open" a new X11 display if you can't get a current one. |
You can create a glx display without a present display, just saying, the same with EGL, you can use EGL_DEFAULT_DISPLAY and it's a valid thing to do on X11 and sort of works(at least that's how it was initially iirc). I think it's a better to use @madsmtm you can set |
Agreed, that's also what I've set out to do.
Done.
So |
Tagging @Lokathor, you may remember the previous discussion on this topic better than I |
I would personally be against this, for the reasoning above. This API affords itself to be misused. |
I am not experienced enough in X11, I'll let you two discuss what the best way forward is. In any case, |
I am mildly against this because NonNull is more of a pain in the butt to work with. Using However, if everyone else really want to use NonNull I won't block the change. |
But |
The downstream already must validate before using data, but with nonnull they can pass data as is, because it's just a pointer. And they could even pass pointer, but for example in glutin we check every input we have. Though, I understand why we have |
The actual function bindings almost never accept Option |
Yeah, that's fair, and the cast won't work because it's not trivial, so you have only an option to transmute, I guess. |
And I have been advised that, in general, transmute and pointers should not be anywhere near each other, because in some cases that look fine the provenance can become messed up, and it's just much safer to never mix them. |
Yeah, I think raw pointers is fine. Do you have any opinion wrt plain |
My opinion is that ensuring greater correctness throughout the trait PointerExt<T: ?Sized> {
fn as_ptr(self) -> *mut T;
}
impl<T: ?Sized> PointerExt<T> for Option<NonNull<T>> {
fn as_ptr(self) -> *mut T { self.map(NonNull::get).unwrap_or(null()) }
} I am still in favor of the PR in its current form, as it prevents a footgun that is very prevalent throughout the users of |
Do we want to do anything with XID on X11, zero is not a valid xid if it matters. |
Yes, I think we should make XID types non-zero as well, at least for XCB, since the Xlib one relies on |
I've moved the |
This is a conservative choice for now; we can later iterate on this decision, and figure out if the handles should actually be non-null.
I went with making the handles nullable, since it's the conservative choice, and then we can discuss that in detail in #141 later. I'll consider this PR ready now, and will merge it in a few days unless someone brings up objections. |
The `windows` crate treats these as `isize` rather than raw void pointers: https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/Foundation/struct.HWND.html And `raw-window-handle 0.6` recently started to do the same: rust-windowing/raw-window-handle#136 However, the win32 documentation still states that these should be `PVOID`: https://learn.microsoft.com/en-us/windows/win32/winprog/windows-data-types
The `windows` crate treats these as `isize` rather than raw void pointers: https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/Foundation/struct.HWND.html And `raw-window-handle 0.6` recently started to do the same: rust-windowing/raw-window-handle#136 However, the win32 documentation still states that these should be `PVOID`: https://learn.microsoft.com/en-us/windows/win32/winprog/windows-data-types
The `windows` crate treats these as `isize` rather than raw void pointers: https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/Foundation/struct.HWND.html And `raw-window-handle 0.6` recently started to do the same: rust-windowing/raw-window-handle#136 However, the win32 documentation still states that these should be `PVOID`: https://learn.microsoft.com/en-us/windows/win32/winprog/windows-data-types
The `windows` crate treats these as `isize` rather than raw void pointers: https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/Foundation/struct.HWND.html And `raw-window-handle 0.6` recently started to do the same: rust-windowing/raw-window-handle#136 However, the win32 documentation still states that these should be `PVOID`: https://learn.microsoft.com/en-us/windows/win32/winprog/windows-data-types
/// A Win32 `HWND` handle. | ||
pub hwnd: *mut c_void, | ||
/// The `HINSTANCE` associated with this type's `HWND`. | ||
pub hinstance: *mut c_void, | ||
pub hwnd: NonZeroIsize, | ||
/// The `GWLP_HINSTANCE` associated with this type's `HWND`. | ||
pub hinstance: Option<NonZeroIsize>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also for posterity: the type was changed from pointer to isize
here to match the representation in Windows-rs: microsoft/windows-rs#1643
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI, win32metadata
is changing these back to void pointers it seems:
microsoft/win32metadata#1924
microsoft/win32metadata@b4dfd2f
See also my local regeneration: microsoft/windows-rs@96b9a27
CC @kennykerr, @riverar, @mikebattista.
A lot of consumers of
raw-window-handle
assume that the pointers are non-null, which makes those libraries unsound. Since the traits are fallible nowadays, we should try to use the type-system to ensure that the handles are always completely valid, instead of expecting user to check it themselves.This could be done by using
Option<NonNull<c_void>>
, but that still needs the user to unwrap what should always be set anyhow, so I opted for renaming theempty
methods tonew
, and taking parameters to these where it makes sense. Note that the structs are still left open to non-breaking extensions, as they are still marked#[non_exhaustive]
- with the caveat that those extensions must be optional / have a sensible default.See #33 and #55 for a bit of previous discussion on this.